package com.flying.acls.adapter.spring;


import com.flying.acls.domain.context.ContextStringValueResolver;
import com.flying.acls.domain.context.DOExpressionContextBuilder;
import com.flying.acls.domain.permission.ClassPermissionBuilder;
import com.flying.acls.domain.resource.DOPatternBasedResourceBuilder;
import com.flying.acls.domain.resource.DOPatternInfo;
import com.flying.acls.domain.service.AclService;
import com.flying.acls.domain.service.AntMatcher;
import com.flying.acls.domain.service.Matcher;
import com.flying.acls.domain.sid.PatternBasedSidBuilder;
import com.flying.acls.domain.sid.SidPatternInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class AclDOConfig {
    @Bean
    public ContextStringValueResolver stringValueResolver() {
        return new ContextStringValueResolver();
    }

    @Bean
    public DOExpressionContextBuilder doExpressionContextBuilder() {
        return new DOExpressionContextBuilder(stringValueResolver());
    }

    @Bean
    public DOPatternBasedResourceBuilder doResourceBuilder() {
        Map<String, DOPatternInfo> doPatternInfos = new HashMap<>();
        DOPatternInfo info = new DOPatternInfo("com.flying.acls.model.Resource", Arrays.asList("${rcn}.${type}"));
        doPatternInfos.put(info.getClassName(), info);
        return new DOPatternBasedResourceBuilder(stringValueResolver(), doPatternInfos);
    }

    @Bean
    public PatternBasedSidBuilder sidBuilder() {
        SidPatternInfo info = new SidPatternInfo(Collections.emptyList());
        return new PatternBasedSidBuilder(stringValueResolver(), info);
    }

    @Bean
    public ClassPermissionBuilder permissionBuilder() {
        return new ClassPermissionBuilder();
    }

    @Bean
    public Matcher antMatcher() {
        return new AntMatcher();
    }

    @Autowired
    private AclService aclService;

    @Bean
    public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService);
        expressionHandler.setPermissionEvaluator(permissionEvaluator);
//        expressionHandler.setPermissionCacheOptimizer(new AclPermissionCacheOptimizer(aclService()));
        return expressionHandler;
    }
}